﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using MonoEX;
public static class CHttp
{

    public static void HttpGetAsync(string url, Action<string> callBack, Encoding encoding = null)
    { 
        Task.Run(
            () =>
            {
                try
                {
                    using (var t = _HttpGetAsync(url,  encoding))
                    {
                        t.Wait();

                        callBack?.Invoke(t.Result);
                    }
                }
                catch (Exception ex)
                {
                    Logout.Warning(ex.ToString());
                    callBack?.Invoke(null);
                }
            }
            );

    }

    static async Task<string> _HttpGetAsync(string url,  Encoding encoding = null)
    {
        string msg = null;
        try
        {
            using (HttpClient http = new HttpClient())
            {
                var message = await http.GetAsync(url);
                if (message != null && message.StatusCode == HttpStatusCode.OK)
                {
                    using (message)
                    {
                        using (Stream responseStream = await message.Content.ReadAsStreamAsync())
                        {
                            if (responseStream != null)
                            {
                                byte[] responseData = new byte[responseStream.Length];
                                responseStream.Read(responseData, 0, responseData.Length);
                                if (encoding == null) encoding = Encoding.UTF8;
                                msg = encoding.GetString(responseData);
                            }
                        }
                    }
                }
            }
        }catch(Exception ex)
        {
            Logout.Error(ex.ToString());
        }
        return msg;
    }



    /// <summary>
    /// Http Get 同步方法
    /// </summary>
    /// <param name="url"></param>
    /// <param name="encoding"></param>
    /// <returns></returns>
    public static string HttpGet(string url, Encoding encoding = null)
    {
        try
        {
            HttpClient httpClient = new HttpClient();
            using (var t = httpClient.GetByteArrayAsync(url))
            {
                t.Wait();

                if (encoding == null) encoding = Encoding.UTF8;
                var ret = encoding.GetString(t.Result);
                return ret;
            }
        }catch(Exception ex)
        {
            Logout.Warning( ex.ToString());
            return null;
        }
    }

    public static void HttpPostKeyValueAsync(
        string url,
        Action<string> callBack,
        List<KeyValuePair<string, string>> formData = null, 
        string charset = "UTF-8",
        string mediaType = "application/x-www-form-urlencoded"
        )
    {
        Task.Run(
            () =>
            {
                try
                {
                    using (var t = _HttpPostKeyValueAsync(url, callBack, formData, charset, mediaType))
                    {
                        t.Wait();
                        callBack(t.Result);
                    }
                }
                catch (Exception ex)
                {
                    Logout.Warning(ex.ToString());
                    callBack(null);
                }
            }
            );

        
    }

    static async Task<string> _HttpPostKeyValueAsync(
        string url,
        Action<string> callBack,
        List<KeyValuePair<string, string>> formData,
        string charset,
        string mediaType
        )
    {
        string tokenUri = url;
        var client = new HttpClient();
        //client.BaseAddress = new Uri(uri);
        HttpContent content = new FormUrlEncodedContent(formData);
        content.Headers.ContentType = new MediaTypeHeaderValue(mediaType);
        content.Headers.ContentType.CharSet = charset;
        for (int i = 0; i < formData.Count; i++)
        {
            content.Headers.Add(formData[i].Key, formData[i].Value);
        }

        HttpResponseMessage resp = await client.PostAsync(tokenUri, content);
        resp.EnsureSuccessStatusCode();
        string token = await resp.Content.ReadAsStringAsync();
        return token;
    }

    public static void HttpPostAsync(string url, Action<string> callBack,   string formData = null, Encoding encoding = null, int timeOut = 10000)
    {
        Task.Run(
            () =>
            {
                try
                {
                    using (var t = _HttpPostAsync(url, formData, encoding,timeOut))
                    {
                        t.Wait();
                        callBack(t.Result);
                    }
                }
                catch (Exception ex)
                {
                    Logout.Warning( ex.ToString());
                    callBack(null);
                }
            }
            );
    }

    static async  Task<string> _HttpPostAsync(string url, string formData = null, Encoding encoding = null, int timeOut = 10000)
    {
        try
        {
            using (HttpClientHandler handler = new HttpClientHandler())
            {
                using (HttpClient client = new HttpClient(handler))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        FillFormDataStream(formData,ms);//填充formData
                        using (HttpContent hc = new StreamContent(ms))
                        {
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml", 0.9));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/webp"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*", 0.8));
                            hc.Headers.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36");
                            hc.Headers.Add("Timeout", timeOut.ToString());
                            hc.Headers.Add("KeepAlive", "true");

                            using (var t = client.PostAsync(url, hc))
                            {
                                using (var r = await t)
                                {
                                    using (var t2 = r.Content.ReadAsByteArrayAsync())
                                    {
                                        var tmp = await t2;
                                        if (encoding == null) encoding = Encoding.UTF8;
                                        return encoding.GetString(tmp);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }catch(Exception ex)
        {
            Logout.Warning( ex.ToString());
            return null;
        }
    }


    public static string HttpPost(string url,   string  formData = null, Encoding encoding =null, int timeOut = 10000)
    {
        try
        {

            using (HttpClientHandler handler = new HttpClientHandler())
            {

                using (HttpClient client = new HttpClient(handler))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        if(formData!=null) FillFormDataStream(formData,ms);//填充formData
                        using (HttpContent hc = new StreamContent(ms))
                        {
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml", 0.9));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/webp"));
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*", 0.8));
                            hc.Headers.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36");
                            hc.Headers.Add("Timeout", timeOut.ToString());
                            hc.Headers.Add("KeepAlive", "true");

                            using (var t = client.PostAsync(url, hc))
                            {
                                t.Wait();
                                using (var t2 = t.Result.Content.ReadAsByteArrayAsync())
                                {
                                    t2.Wait();
                                    if (encoding == null) encoding = Encoding.UTF8;
                                    return encoding.GetString(t2.Result);
                                }
                            }
                        }
                    }
                }
            }
        }catch(Exception ex)
        {
            Logout.Warning( ex.ToString());
            return null;
        }
    }

    /*public static string GetQueryString(Dictionary<string, string> formData)
    {
        if (formData == null || formData.Count == 0)
        {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        var i = 0;
        foreach (var kv in formData)
        {
            i++;
            sb.AppendFormat("{0}={1}", kv.Key, kv.Value);
            if (i < formData.Count)
            {
                sb.Append("&");
            }
        }

        return sb.ToString();
    }*/
     


    static void FillFormDataStream(string formData, Stream stream)
    {
        var formDataBytes = formData == null ? new byte[0] : Encoding.UTF8.GetBytes(formData);
        stream.Write(formDataBytes, 0, formDataBytes.Length);
        stream.Seek(0, SeekOrigin.Begin);//设置指针读取位置
    }
}